package com.dgut.springsecurity.handler;

import com.dgut.springsecurity.Details.UserAccountDetailService;
import com.dgut.usermanager.entity.UserAccount;
import com.dgut.usermanager.service.UserAccountService;
import es.moki.ratelimitj.core.limiter.request.RequestLimitRule;
import es.moki.ratelimitj.core.limiter.request.RequestRateLimiter;
import es.moki.ratelimitj.inmemory.request.InMemorySlidingWindowRequestRateLimiter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Component
public class UserLoginFailureHandler extends SimpleUrlAuthenticationFailureHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(UserLoginFailureHandler.class);

    @Autowired
    UserAccountService userAccountService;
    @Autowired
    UserAccountDetailService userAccountDetailService;

    Set<RequestLimitRule> rules= Collections.singleton(RequestLimitRule.of(1,TimeUnit.MINUTES,2));
    RequestRateLimiter limiter = new InMemorySlidingWindowRequestRateLimiter(rules);

    ScheduledExecutorService scheduledExecutorService= Executors.newScheduledThreadPool(1);
    boolean reachLimit=false;
    String errMsg=null;
    Integer number=3 ;
    Long rest=0l;
    Long n=0l;
    Long start=0l;
    Long end=0l;

    public Integer getNumber() {
        return number;
    }

    public void setNumber(Integer number) {
        this.number = number;
    }

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {

        LOGGER.error("登录错误 [{}] ",exception.getMessage());
        response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
        response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        //request.setCharacterEncoding("utf-8");
        PrintWriter writer = response.getWriter();
        String username=request.getParameter("username");
        String password=request.getParameter("password");
        UserAccount userAccount= userAccountService.findUserAccountByAccount(username);
        reachLimit=limiter.overLimitWhenIncremented(username);
        if(reachLimit&&!userAccountDetailService.isReachLimit()){
            /*org.springframework.security.core.userdetails.User updated = new org.springframework.security.core.userdetails.User(u.getUsername(),u.getPassword(),u.isEnabled(),u.isAccountNonExpired(),u.isAccountNonExpired(),false,u.getAuthorities());
            userDetailsManager.updateUser(updated);*/
            userAccountDetailService.setReachLimit(reachLimit);
            start=System.currentTimeMillis();
            scheduledExecutorService.schedule(() -> {
                userAccountDetailService.setReachLimit(false);
                number=3;
                System.out.println("ScheduledTask"+reachLimit);
            },2 , TimeUnit.MINUTES);
            System.out.println("cscd");
        }
        if(reachLimit){
            end=System.currentTimeMillis();
            n=(end-start)/(1000*60);
            rest=2-n;
            errMsg="该用户名已被锁定！！！"+rest+"分钟后解锁";
            errMsg=URLEncoder.encode(errMsg,"utf8");
            System.out.println("cscd");
            //response.sendRedirect("/user/attribute?errMsg="+errMsg);
            writer.write("该用户名已被锁定！！！"+rest+"分钟后解锁");
            writer.flush();
            writer.close();
        }
        if(userAccount==null){
            number--;
            //errMsg="用户名不存在！！！"+number+"次机会尝试";
            errMsg="用户名不存在,同一用户名最多只能尝试3次登录！！！";
            errMsg=URLEncoder.encode(errMsg,"utf8");
            response.sendRedirect("/user/attribute?errMsg="+errMsg);
            //writer.write("用户名不存在！！！"+number+"次机会尝试");
        }else if(userAccount.getPassword()!=password){
            number--;
            //errMsg="密码错误！！！"+number+"次机会尝试";
            errMsg="密码错误,同一用户名最多只能尝试3次登录！！！";
            errMsg=URLEncoder.encode(errMsg,"utf8");
            response.sendRedirect("/user/attribute?errMsg="+errMsg);
            //writer.write("密码错误！！！"+number+"次机会尝试");*/
        }
        //writer.write(exception.getMessage());

    }
}

